import json
from src.core import log
from src.db import dbm, dbs
from src.schema import Schema
from src.core.variables.info import sof
from sqlalchemy.orm import scoped_session
from src.core.nodes.certification import Cert
from src.core.variables.function import CREATE_ID
from src.core.variables.status import ERROR_CODE, SUCCESS_CODE, SUCCESS_CODE_CUSTOMIZE


def bind(schema: Schema.nodes_bind):
    with dbm.get("sys_default") as db_session:
        db_session: scoped_session
        data = Cert().analyze_certificate(schema.cert)
        ip = data.get("ip", None)
        port = data.get("port", None)
        node_id= data.get("node_id", None)
        registered = (
            db_session.query(dbs.sys_default.Node)
            .filter(dbs.sys_default.Node.ip == ip)
            .first()
        )
        if registered:
            return ERROR_CODE.NODE_REGISTERED()
        else:
            db_session.add(
                dbs.sys_default.Node(
                    node_id=node_id,
                    host=ip,
                    ip=ip,
                    port=port,
                    status="enable",
                    os_type="",
                    os_version="",
                    kernel_version="",
                    cpu_cores="",
                    cpu_instruction_set="",
                    cpu_model="",
                    mem_size="",
                    disk_info="",
                    certificate=str(json.dumps(eval(schema.cert))),
                )
            )
            try:
                if dbm.commit(db_session):
                    return SUCCESS_CODE.NODE_REGISTER_SUCCESS()
                else:
                    db_session.rollback()
                    return ERROR_CODE.SUBMISSION_FAILED()
            finally:
                init_new_node()


def all_nodes():
    with dbm.get(f"sys_default") as db_session:
        db_session: scoped_session
        db_result = db_session.query(dbs.sys_default.Node).all()
        result = []
        for i in db_result:
            result.append(
                {
                    "node_id": i.node_id,
                    "host": i.host,
                    "ip": i.ip,
                }
            )
        return SUCCESS_CODE_CUSTOMIZE(result, code=200)


def init_new_node():
    """新节点绑定成功后初始化数据"""
    log.INFO(f"节点绑定成功，开始初始化数据...")


def bind_info():
    """获取绑定信息"""
    with dbm.get("sys_default") as db_session:
        db_session: scoped_session
        db_result = (
            db_session.query(dbs.sys_default.Node)
            .filter(dbs.sys_default.Node.host == "localhost")
            .first()
        )
        if db_result:
            return SUCCESS_CODE.CERT_INFO(eval(db_result.certificate))
        else:
            return SUCCESS_CODE.CERT_INFO(eval(Cert().create_certificate()))


def unbind_node(schema: Schema.unbind_node):
    """节点解绑"""
    with dbm.get("sys_default") as db_session:
        db_session: scoped_session
        db_result = (
            db_session.query(dbs.sys_default.Node)
            .filter(dbs.sys_default.Node.node_id == schema.node_id)
            .first()
        )
        if db_result:
            db_session.delete(db_result)
        if dbm.commit(db_session):
            return SUCCESS_CODE.NODE_UNBIND_SUCCESS()
        else:
            db_session.rollback()
            return ERROR_CODE.SUBMISSION_FAILED()


def compile_status():
    return [
        {"name": "nginx", "status": str(sof.fm_nginx)},
        {"name": "unzip", "status": str(sof.fm_unzip)},
    ]
